﻿using Newtonsoft.Json;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;
using Yz.Base;
using Yz.Base.Enums;
using Yz.Base.MqModels;
using Yz.Core.Base;

namespace Yz.Mq
{
    public class MqFactory<T> : IMqFactory<T>, IDependency where T : MqModel
    {
        #region 创建mqdata

        /// <summary>
        ///     组装MQData（单个model）
        /// </summary>
        /// <param name="model"></param>
        /// <param name="mqType"></param>
        /// <returns></returns>
        public MqData<T> CreateMQData(T model, OperateType operateType)
        {
            return new MqData<T>
            {
                operateType = operateType,
                data = model
            };
        }

        /// <summary>
        ///     组装MQData（modellist）
        /// </summary>
        /// <param name="models"></param>
        /// <param name="mqType"></param>
        /// <returns></returns>
        public MqData<List<T>> CreateMQData(List<T> models, OperateType operateType)
        {
            return new MqData<List<T>>
            {
                operateType = operateType,
                data = models
            };
        }

        #endregion 创建mqdata

        #region 发布

        /// <summary>
        ///     发布消息
        /// </summary>
        /// <param name="data"></param>
        /// <param name="exchangeName"></param>
        public void PublishMQ(MqData<T> data, string exchangeName)
        {
            var factory = GetMqConnFact();
            var msgBodyBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
            using (var conn = factory.CreateConnection())
            {
                using (var channel = conn.CreateModel())
                {
                    var props = channel.CreateBasicProperties();
                    props.ContentType = "text/plain";
                    props.DeliveryMode = 2; ///持久化
                    channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout, true);
                    channel.BasicPublish(exchangeName, "", props, msgBodyBytes);
                }
            }
        }

        /// <summary>
        ///     发布消息
        /// </summary>
        /// <param name="datas"></param>
        /// <param name="exchangeName"></param>
        public void PublishMQ(MqData<List<T>> datas, string exchangeName)
        {
            var factory = GetMqConnFact();
            var msgBodyBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(datas));
            using (var conn = factory.CreateConnection())
            {
                using (var channel = conn.CreateModel())
                {
                    var props = channel.CreateBasicProperties();
                    props.ContentType = "text/plain";
                    props.DeliveryMode = 2; ///持久化
                    channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout, true);
                    channel.BasicPublish(exchangeName, "", props, msgBodyBytes);
                }
            }
        }

        #endregion 发布

        /// <summary>
        ///     实例化mqConnectionFactory
        /// </summary>
        /// <returns></returns>
        private ConnectionFactory GetMqConnFact()
        {
            return new ConnectionFactory
            {
                UserName = MqConfig.UserName,
                Password = MqConfig.Password,
                VirtualHost = MqConfig.VirtualHost,
                Port = MqConfig.Port,
                HostName = MqConfig.HostName,
                AutomaticRecoveryEnabled = true,
                NetworkRecoveryInterval = TimeSpan.FromSeconds(10)
            };
        }
    }
}